package dicapi

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"strconv"

	// "time"
	// "github.com/dgrijalva/jwt-go"
	"github.com/labstack/echo"
	"gopkg.in/mgo.v2/bson"

	// "github.com/jinzhu/gorm"
	"oxy_server/middleware"
	"oxy_server/model"
	"oxy_server/module/log"
	"oxy_server/until"

	"golang.org/x/crypto/bcrypt"
)

type (
	user struct {
		ID       bson.ObjectId `json:"_id" bson:"_id"`
		Name     string        `json:"username" bson:"username"`
		Password string        `json:"password" bson:"password"`
		Role     string        `json:"role" bson:"role"`
		RoleName string        `json:"rolename" bson:"rolename"`
		Email    string        `json:"email" bson:"email"`
		Phone    string        `json:"phone" bson:"phone"`
		Brand    []string      `json:"brand" bson:"brand"`
	}
	// 创建人员结构体
	insertUser struct {
		Name     string   `json:"username" bson:"username"`
		Password string   `json:"password" bson:"password"`
		Role     string   `json:"role" bson:"role"`
		RoleName string   `json:"rolename" bson:"rolename"`
		Email    string   `json:"email" bson:"email"`
		Phone    string   `json:"phone" bson:"phone"`
		Brand    []string `json:"brand" bson:"brand"`
	}
)

func CreateUserHandler(c echo.Context) error {
	u := &insertUser{}
	if err := c.Bind(u); err != nil {
		log.Error("解析失败", err)
		c.JSON(403, map[string]interface{}{
			"msg": "error",
		})
		return err
	}
	bytes, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
	u.Password = string(bytes)
	model.DB().Dbname = "OxyCms"
	model.DB().Document = "users"
	err = model.DB().Insert(u)
	if err != nil {
		log.Error("插入出错", err)
		c.JSON(403, map[string]interface{}{
			"msg": "error",
		})
		return nil
	}
	c.JSON(200, map[string]interface{}{
		"msg": "success",
	})
	return nil

}
func GetUserInfoHandler(c echo.Context) error {
	log.Info("GetUserInfoHandler")
	id := c.QueryParam("id")
	model.DB().Dbname = "OxyCms"
	model.DB().Document = "users"
	query, err := model.DB().QueryOne(bson.M{"_id": bson.ObjectIdHex(id)})
	if err != nil {
		c.JSON(403, map[string]interface{}{
			"msg": "error",
		})
		return nil
	}
	p := user{}
	query.One(&p)
	p.Password = ""
	str, err := json.Marshal(p)
	if err != nil {
		c.JSON(403, map[string]interface{}{
			"msg": "error",
		})
		return nil
	}
	c.JSON(200, map[string]interface{}{
		"msg":  "success",
		"data": string(str),
	})

	return nil
}

func EditUserHandler(c echo.Context) error {
	id := c.QueryParam("id")
	u := &insertUser{}
	if err := c.Bind(u); err != nil {
		log.Error("解析失败", err)
		c.JSON(403, map[string]interface{}{
			"msg": "error",
		})
		return nil
	}
	model.DB().Dbname = "OxyCms"
	model.DB().Document = "users"

	p := user{}
	query, err := model.DB().QueryOne(bson.M{"_id": bson.ObjectIdHex(id)})
	query.One(&p)
	s, err := json.Marshal(p)
	bufbody := bytes.NewBuffer(s)
	c.Request().Body = ioutil.NopCloser(bufbody)

	if u.Password != "" {
		u_bytes, _ := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
		u.Password = string(u_bytes)
	} else {
		u.Password = p.Password
	}
	err = model.DB().Update(bson.M{"_id": bson.ObjectIdHex(id)}, u)
	if err != nil {
		log.Error("插入失败", err)
		c.JSON(403, map[string]interface{}{
			"msg": "error",
		})
		return nil
	}

	c.JSON(200, map[string]interface{}{
		"msg": "success",
	})

	return nil
}

func DelUserHandler(c echo.Context) error {
	id := c.QueryParam("id")
	log.Info("id", id)
	model.DB().Dbname = "OxyCms"
	model.DB().Document = "users"
	p := user{}
	query, err := model.DB().QueryOne(bson.M{"_id": bson.ObjectIdHex(id)})
	query.One(&p)
	s, err := json.Marshal(p)
	bufbody := bytes.NewBuffer(s)
	c.Request().Body = ioutil.NopCloser(bufbody)
	err = model.DB().Remove(bson.M{"_id": bson.ObjectIdHex(id)})
	if err != nil {
		c.JSON(403, map[string]interface{}{
			"msg": "error",
		})
	}
	c.JSON(200, map[string]interface{}{
		"msg": "success",
	})
	return nil
}

func GetUserListHandler(c echo.Context) error {
	currentpage, _ := strconv.Atoi(c.QueryParam("currentpage"))
	perpage, _ := strconv.Atoi(c.QueryParam("perpage"))
	jsonquery := c.QueryParam("like")
	M, err := until.JsonToBson(jsonquery)
	if err != nil {
		log.Error("json-> bson 失败", err)
		c.JSON(403, map[string]interface{}{
			"msg": "error",
		})
		return err
	}
	model.DB().Dbname = "OxyCms"
	model.DB().Document = "users"
	query, count, err := model.DB().Query(M, currentpage, perpage)
	if err != nil {
		log.Error("查询出错", err)
	}
	ps := []user{}
	query.All(&ps)

	str, err := json.Marshal(ps)
	c.JSON(200, map[string]interface{}{
		"msg":   "success",
		"data":  string(str),
		"count": count,
	})

	return nil
}

func UserLoginHandler(c echo.Context) error {
	u := &user{}
	if err := c.Bind(u); err != nil {
		return err
	}

	model.DB().Dbname = "OxyCms"
	model.DB().Document = "users"
	query, _, err := model.DB().Query(bson.M{"username": u.Name}, 1, 1)
	if err != nil {
		log.Error("查询出错", err)
		c.JSON(403, map[string]interface{}{
			"msg": "error",
		})
		return err
	}
	ps := []user{}
	query.All(&ps)
	if len(ps) == 0 {
		c.JSON(403, map[string]interface{}{
			"msg":  "error",
			"info": "查询人员失败",
		})
		return nil
	}

	err = bcrypt.CompareHashAndPassword([]byte(ps[0].Password), []byte(u.Password))
	if err != nil {
		c.JSON(403, map[string]interface{}{
			"msg":  "error",
			"info": "login failed",
		})
		return nil
	}
	str, err := json.Marshal(ps)

	t, err := middleware.CreateToken(ps[0].Name, ps[0].Role, ps[0].Password)
	if err != nil {
		return err
	}
	cookie := new(http.Cookie)
	cookie.Name = "token"
	cookie.Value = t
	cookie.Path = "/"
	// cookie.Expires = time.Now().Add(30 * time.Minute)
	c.SetCookie(cookie)

	c.JSON(200, map[string]interface{}{
		"msg":   "success",
		"token": t,
		"data":  string(str),
	})

	return nil
}

func UserLogoutHandler(c echo.Context) error {
	cookie, err := c.Cookie("token")
	if err != nil {
		c.JSON(403, map[string]interface{}{"msg": "获取token失败"})
		return nil
	}
	cookie.Name = "token"
	cookie.Value = ""
	cookie.Path = "/"
	cookie.MaxAge = -1
	c.SetCookie(cookie)

	c.JSON(200, map[string]interface{}{"msg": "success"})
	return nil
}
